package com.nova.bluetooth.manage;

import static com.iflytek.aiui.AIUIConstant.CMD_SET_PARAMS;
import static com.nova.bluetooth.base.CommonMessageWrap.ACTION_AIUI_LISTENER_DATA;
import static com.nova.bluetooth.base.CommonMessageWrap.ACTION_AIUI_TTS_RESULT;
import static com.nova.bluetooth.base.CommonMessageWrap.publishAIUIEventMessage;
import static com.nova.bluetooth.xunFeiSDK.engine.EngineConstants.mAIUIState;
import static com.nova.bluetooth.xunFeiSDK.engine.EngineConstants.meaningful;


import android.content.Context;
import android.media.AudioFormat;
import android.net.wifi.WifiInfo;
import android.net.wifi.WifiManager;
import android.util.Log;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.iflytek.aiui.AIUIAgent;
import com.iflytek.aiui.AIUIConstant;
import com.iflytek.aiui.AIUIEvent;
import com.iflytek.aiui.AIUIListener;
import com.iflytek.aiui.AIUIMessage;
import com.nova.bluetooth.base.CommonMessageWrap;
import com.nova.bluetooth.helpUtils.LogUtil;
import com.nova.bluetooth.helpUtils.SharePreferenceUtils;
import com.nova.bluetooth.helpUtils.ToastUtils;
import com.nova.bluetooth.xunFeiSDK.engine.AiuiEngine;
import com.nova.bluetooth.xunFeiSDK.engine.EngineConstants;
import com.nova.bluetooth.xunFeiSDK.engine.WakeupEngine;
import com.nova.bluetooth.xunFeiSDK.engine.WakeupListener;
import com.nova.bluetooth.xunFeiSDK.recorder.AudioRecorder;
import com.nova.bluetooth.xunFeiSDK.recorder.RecorderFactory;
import com.nova.bluetooth.xunFeiSDK.recorder.SystemRecorder;
import com.nova.bluetooth.xunFeiSDK.utils.ErrorCode;
import com.nova.bluetooth.xunFeiSDK.utils.StreamingAsrUtil;
import com.nova.bluetooth.xunFeiSDK.utils.senselessWordUtil;


import java.io.FileInputStream;
import java.io.InputStream;
import java.nio.charset.StandardCharsets;
import java.util.Objects;
import java.util.Random;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;


public class AiUiManager {
    public static final String TAG = "AiUiManager==》";
    private String SN_LIST[] = {
            "sanag-4dfc02372263c3d8",
            "sanag-d4a55cea2bcaad45",
            "sanag-77b77d4a8777774a",
            "sanag-9ce79e1f9fd34fd1",
            "sanag-d45da98233f8761e",
            "sanag-206c27d3dec3b0a0",
            "sanag-965b6637d49ea90c",
            "sanag-8604b8853f68aae8",
            "sanag-d52af26bbd20392a",
            "sanag-04d74d2887cb9ff5"
    };

    private static volatile AiUiManager instance;
    private AiUiManager() {
        // 私有构造函数，防止外部实例化
    }

    public static AiUiManager getInstance() {
        if (instance == null) {
            synchronized (AiUiManager.class) {
                if (instance == null) {
                    instance = new AiUiManager();
                }
            }
        }
        return instance;
    }


    // AIUI
    private AIUIAgent mAIUIAgent;
    public AIUIAgent getAIUIAgent(){
        return mAIUIAgent;
    }
    private AudioRecorder recorder;

//    private WakeupEngine wakeupEngine;   // 降噪唤醒引擎
//
//    /**
//     * 唤醒回调
//     */
//    private WakeupListener wakeupListener = (angle, beam, score, keyWord) -> {
//
//        KLog.d(TAG, "唤醒成功,angle:" + angle + " beam:" + beam + " score=" + score);
//        KLog.d(TAG, "唤醒词" + keyWord);
//        // InteractUtil.startTimer();
//        // CAE SDK触发唤醒后给AIUI SDK发送手动唤醒事件：让AIUI SDK置于工作状态
//    };

    public StringBuffer stringBuffer = new StringBuffer();
    public String asrResult = "";
    /**
     * AIUI 回调信息处理
     */
    private AIUIListener aiuiListener = this::onEvent;

    //aiui配置文件在assets下的路径
//    private static String aiuiCfgPath = "cfg/aiui_kugouDemo.cfg";
    private final static String aiuiCfgPath = "cfg/aiui.cfg";
    private final static String aiuiCfgPath_gpt_chat = "cfg/aiui_gpt_chat.cfg";
    private final static String aiuiCfgPath_gpt_chat_wakeup = "cfg/aiui_gpt_chat_wakeup.cfg";
    private String mAiuiCfgPath = aiuiCfgPath;

    public final static String AIUI_SN_KEY = "aiui_sn";
    public void initWakeupAIUIAgent(Context context) {
        String mNetSN = (String) SharePreferenceUtils.get(context, AIUI_SN_KEY, "");
        if (mNetSN != null && !mNetSN.isEmpty()) {  //先查一下有没有从服务端拉取到SN
            EngineConstants.serialNumber = mNetSN;
            LogUtil.d("test==> NetSN serialNumber = " + mNetSN);
        } else {                                    //没有再读取默认的
            Random random = new Random();
            int randomNumber = random.nextInt(SN_LIST.length);
            if (EngineConstants.serialNumber == null || !EngineConstants.serialNumber.contains("sanag-")) {//已经有序列号，直接使用
                EngineConstants.serialNumber = SN_LIST[randomNumber];
            }
            LogUtil.d("test==> serialNumber = " + EngineConstants.serialNumber + " randomNumber = " + randomNumber);
        }

        // 初始化AIUI(识别+语义+合成）
        mAIUIAgent = AiuiEngine.getInstance(aiuiListener, mAiuiCfgPath);
        if (mAIUIAgent != null) {
            Log.d(TAG, "AIUI初始化成功");
        } else {
            Log.e(TAG, "AIUI初始化失败");
        }
    }

    public void initAiUi(Context context) {
        destroyAiUiAllEngine();

        EngineConstants.isWriting = false;

        String mNetSN = (String) SharePreferenceUtils.get(context, AIUI_SN_KEY, "");
        if (mNetSN != null && !mNetSN.isEmpty()) {  //先查一下有没有从服务端拉取到SN
            EngineConstants.serialNumber = mNetSN;
            LogUtil.d("test==> NetSN serialNumber = " + mNetSN);
        } else {                                    //没有再读取默认的
            Random random = new Random();
            int randomNumber = random.nextInt(SN_LIST.length);
            if (EngineConstants.serialNumber == null || !EngineConstants.serialNumber.contains("sanag-")) {//已经有序列号，直接使用
                EngineConstants.serialNumber = SN_LIST[randomNumber];
            }
            LogUtil.d("test==> serialNumber = " + EngineConstants.serialNumber + " randomNumber = " + randomNumber);
        }

        mAIUIAgent = AiuiEngine.getInstance(aiuiListener, mAiuiCfgPath);
        checkAIUIEngine();
    }

    /**
     * 讯飞 Sanag 下的配置
     *
     * @param context
     */
    public void initSDK(Context context) {
        destroyAiUiAllEngine();

        //状态初始化
        mAiuiCfgPath = aiuiCfgPath;
        initAiUi(context);
        setWakeupMsg();
        setScene(true);
        setSpeechTimeout(0.7f, 700, 5000);
    }

    /**
     * 目前暂时也是讯飞 Sanag 下的配置key, 后面应该会用另外的配置 appid
     *
     * @param context
     */
    public void initSDKLongTimeout(Context context) {
        destroyAiUiAllEngine();

        //状态初始化
        mAiuiCfgPath = aiuiCfgPath_gpt_chat;
        initAiUi(context);
        setWakeupMsg();
        setAIChatScene();
        setSpeechTimeout(0.3f, 700, 3000);
        AiuiEngine.TTS_playByUser();
    }


    /**
     * 语音唤醒AIUI初始化
     * @param context
     */
    public void initAIUISDKWakeup(Context context) {
        destroyAiUiAllEngine();

        //状态初始化
        mAiuiCfgPath = aiuiCfgPath_gpt_chat_wakeup;
        initWakeupAIUIAgent(context);
        setAIChatScene();
        setSpeechTimeout(0.3f, 700, 3000);
    }

    public void initWakeupEngine() {
        //初始化CAE(降噪+唤醒)
        wakeupEngine = WakeupEngine.getInstance(wakeupListener);
        if (wakeupEngine != null) {
            Log.i(TAG, "wakeupEngine初始化成功");
        } else {
            Log.e(TAG, "wakeupEngine初始化失败");
        }
        setWakeupStatus();

        //初始化录音
        if (recorder == null) {
            recorder = RecorderFactory.getRecorder();
        }
        if (recorder != null) {
            Log.i(TAG, "录音机初始化成功");
            setWakeupStatus();
        } else {
            Log.i(TAG, "录音机初始化失败");
        }
    }

    public void destroyAiUiAllEngine() {
        if (EngineConstants.isRecording) {
            stopRecord();
        }
        if (recorder != null) {
            recorder.destroyRecord();
            recorder = null;
        }
        WakeupEngine.destroy();
        //销毁aiui
        AiuiEngine.destroy();

        if (mAIUIAgent != null){
            mAIUIAgent.destroy();
            mAIUIAgent = null;
        }
    }

    private void setMainScene() {
        String setParams = "{\"global\":{\"scene\":\"main_box\"}}";
        AIUIMessage setMsg = new AIUIMessage(CMD_SET_PARAMS, 0, 0, setParams, null);
        mAIUIAgent.sendMessage(setMsg);
    }


    private WakeupEngine wakeupEngine;   // 降噪唤醒引擎
    private static final boolean isWakeup = true;  //默認開啟語音喚醒功能

    /**
     * 唤醒回调
     */
    private WakeupListener wakeupListener;

    public void setWakeupListener(WakeupListener wakeupListener) {
        this.wakeupListener = wakeupListener;
    }

    public void resetWakeup() {
        AiuiEngine.MSG_reset_wakeup();
    }

    private void setWakeupStatus() {
        SystemRecorder.AUDIO_TYPE_ASR = !isWakeup;
    }


    public boolean checkAIUIEngine() {
        if (mAIUIAgent != null) {
            LogUtil.d("AIUI初始化成功");
            return true;
        } else {
            LogUtil.d("AIUI初始化失败");
            return false;
        }
    }

    private void setWakeupMsg() {
        if (mAIUIAgent != null) {
            AIUIMessage wakeupMsg = new AIUIMessage(AIUIConstant.CMD_WAKEUP, 0, 0, "", null);
            mAIUIAgent.sendMessage(wakeupMsg);
        }
    }


    public static String getMacAddress(Context context) {
        WifiManager wifiManager = (WifiManager) context.getSystemService(Context.WIFI_SERVICE);
        WifiInfo wifiInfo = wifiManager.getConnectionInfo();
        return wifiInfo.getMacAddress();
    }

    /**
     * 情景模式设置(AIUI应用场景设置)
     *
     * @param isChineseScene 默认中文， false 为英文模式
     */
    public void setScene(boolean isChineseScene) {
        if (!checkAIUIEngine()) return;

        String setParams = "";
        if (isChineseScene) {
            setParams = "{\"global\":{\"scene\":\"main_box\"}}";
        } else {
            setParams = "{\"global\":{\"scene\":\"en-main_box\"}}";
        }
        AIUIMessage setMsg = new AIUIMessage(CMD_SET_PARAMS, 0, 0, setParams, null);
        mAIUIAgent.sendMessage(setMsg);
    }

    public void setAIChatScene() {
        if (!checkAIUIEngine()) return;
        String setParams = "{\"global\":{\"scene\":\"aichat_box\"}}";
        AIUIMessage setMsg = new AIUIMessage(CMD_SET_PARAMS, 0, 0, setParams, null);
        mAIUIAgent.sendMessage(setMsg);
    }

    public void initRecorder() {
        //数据处理模式,true(不降噪唤醒直接识别,16k16bit,1声道)
        SystemRecorder.AUDIO_TYPE_ASR = true;
        //false(先降噪唤醒再识别，16k16bit,2声道)
//        SystemRecorder.AUDIO_TYPE_ASR = false;
        //初始化录音
        if (recorder == null) {
            recorder = RecorderFactory.getRecorder();
        }
        if (recorder != null) {
            LogUtil.d("录音机初始化成功");
        } else {
            LogUtil.d("录音机初始化失败");
        }
        startRecord();
    }

    public void startWakeupRecord() {
        if (recorder != null) {
            int ret = recorder.startRecord();
            if (0 == ret) {
                Log.d(TAG, "开启录音成功");
            } else if (111111 == ret) {
                Log.e(TAG, "异常,AlsaRecorder is null ...");
            } else {
                Log.e(TAG, "开启录音失败，请查看/dev/snd/下的设备节点是否有777权限！" +
                        "\nAndroid 8.0 以上需要暂时使用setenforce 0 命令关闭Selinux权限！");
                destroyRecord();
            }
        }
    }

    private void startRecord() {
        if (recorder != null) {
            int ret = recorder.startRecord();
            if (0 == ret) {
                LogUtil.d("开启录音成功！");
            } else if (111111 == ret) {
                LogUtil.d("异常,AlsaRecorder is null ...");
            } else {
                LogUtil.d("开启录音失败，请查看/dev/snd/下的设备节点是否有777权限！\nAndroid 8.0 以上需要暂时使用setenforce 0 命令关闭Selinux权限！");
                destroyRecord();
            }
        }

        if (onAiUiRecognizeListener != null) {
            onAiUiRecognizeListener.onRecordStatus(true);
        }
    }

    public void stopRecord() {
        if (recorder != null) {
            recorder.stopRecord();
            LogUtil.d("停止录音");
        }
        if (onAiUiRecognizeListener != null) {
            onAiUiRecognizeListener.onRecordStatus(false);
        }
    }

    private void destroyRecord() {
        stopRecord();
        recorder = null;
        LogUtil.d("destroy is Done!");
    }

    public void startVoiceNlp() {
        if (null == mAIUIAgent) {
            Log.e(TAG, "AIUIAgent为空，请先初始化SDK");
            return;
        }

        Log.i(TAG, "start voice nlp");

        // 先发送唤醒消息，改变AIUI内部状态，只有唤醒状态才能接收语音输入
        // 默认为oneshot模式，即一次唤醒后就进入休眠。可以修改aiui_phone.cfg中speech参数的interact_mode为continuous以支持持续交互
        AIUIMessage wakeupMsg = new AIUIMessage(AIUIConstant.CMD_WAKEUP, 0, 0, "", null);
        mAIUIAgent.sendMessage(wakeupMsg);

        // 打开AIUI内部录音机，开始录音。若要使用上传的个性化资源增强识别效果，则在参数中添加pers_param设置
        // 个性化资源使用方法可参见http://doc.xfyun.cn/aiui_mobile/的用户个性化章节
        // 在输入参数中设置tag，则对应结果中也将携带该tag，可用于关联输入输出
        String params = "sample_rate=16000,data_type=audio,pers_param={\"uid\":\"\"},tag=audio-tag";
        AIUIMessage startRecord = new AIUIMessage(AIUIConstant.CMD_START_RECORD, 0, 0, params, null);
        mAIUIAgent.sendMessage(startRecord);
    }

    public void stopVoiceNlp() {
        if (null == mAIUIAgent) {
            Log.e(TAG, "AIUIAgent 为空，请先初始化SDK");
            return;
        }

        Log.i(TAG, "stop voice nlp");
        // 停止录音
        String params = "sample_rate=16000,data_type=audio";
        AIUIMessage stopRecord = new AIUIMessage(AIUIConstant.CMD_STOP_RECORD, 0, 0, params, null);
        mAIUIAgent.sendMessage(stopRecord);
    }

    private final ExecutorService ttsExecutorService = Executors.newSingleThreadExecutor();

    public void startTTSBySdk(String text) {
        // 设置tts为sdk自动播放(演示方便，实际产品手动控制播放比较方便)
//        ttsExecutorService.submit(() -> {
            AiuiEngine.TTS_playBySdk();
            startTTS(text);
//        });
    }


    public void startTTSByUser(String text) {
        //动态设置参数，将tts设置为手动播放
        AiuiEngine.TTS_playByUser();
        startTTS(text);
    }

    public static boolean TTSIsStart = false;
    public static int TTS_SPEED = 48;
    public static int TTS_PITCH = 53;
    public static int TTS_VOLUME = 50;
    public static String TTS_ROBOT = "x2_xiaojuan";//x2_miya  x2_xiaojuan
    public static final String TTS_ROBOT_PERSON1 = "x4_lingxiaoxuan_chat";
    public static final String TTS_ROBOT_PERSON2 = "x4_lingxiaoying_em_v2";
    public static final String TTS_ROBOT_PERSON3 = "x2_xiaojuan";
    public static final String TTS_ROBOT_PERSON4 = "x_dangdang";
    public static final String TTS_ROBOT_PERSON5 = "x_qige";


    //聆小璇 x4_lingxiaoxuan_chat 普通话 中性女声 V4.0版本，效果较好
    //聆小樱 x4_lingxiaoying_em_v2 普通话 温柔女声 V4.0版本，效果较好
    //小娟 x2_xiaojuan 普通话 温柔女声 V2.0版本
    //小飞小姐姐 x_dangdang 普通话 青年女声 V1.0版本
    //小飞小哥哥 x_qige 普通话 青年男声 V1.0版本
    private void startTTS(String text) {
        if (text == null){
            return;
        }

        text = text.isEmpty() ? "请输入合成文本" : text;
        //构建合成参数
        StringBuffer params = new StringBuffer();
        //合成发音人，x2_xiaojuan默认免费，其他需要付费开通,发音人列表：https://www.yuque.com/iflyaiui/zzoolv/iwxf76
        params.append("vcn=" + TTS_ROBOT);
        //语速，取值范围[0,100]
        params.append(",speed=" + TTS_SPEED);
        //音调，取值范围[0,100]
        params.append(",pitch=" + TTS_PITCH);
        //音量，取值范围[0,100]
        params.append(",volume=" + TTS_VOLUME);
        AiuiEngine.TTS_start(text, params);
        TTSIsStart = true;
    }


//    private void setTTS(String text) {
//        AiuiEngine.TTS_playBySdk();
//
////        LogUtil.d("test==>isPlayingBeforeTTS:" + isPlayingBeforeTTS);
//        mAudioFocusManager.requestFocus();
//        text = text.isEmpty() ? "请输入合成文本" : text;
//        //构建合成参数
//        StringBuffer params = new StringBuffer();
//        //合成发音人，x2_xiaojuan默认免费，其他需要付费开通,发音人列表：https://www.yuque.com/iflyaiui/zzoolv/iwxf76
//        params.append("vcn=" + AIUI_SERVICE_TTS_ROBOT);
////        //语速，取值范围[0,100]
////        params.append(",speed=30");
////        //音调，取值范围[0,100]
////        params.append(",pitch=50");
////        //音量，取值范围[0,100]
////        params.append(",volume=90");
//        AiuiEngine.TTS_start(text, params);
//    }

    public void pauseTTS() {
        AiuiEngine.TTS_pause();
    }

    public void resumeTTS() {
        AiuiEngine.TTS_resume();
    }

    public void stopTTS() {
        if (TTSIsStart) {
            AiuiEngine.TTS_stop();
        }
        TTSIsStart = false;
    }

    public void clearRecognitionText() {
        asrResult = "";
        if (stringBuffer.length() > 0) {
//            stringBuffer.delete(0, stringBuffer.length());
            stringBuffer.setLength(0);
        }
        LogUtil.d("stringBuffer = " + stringBuffer.toString());
    }


    private void onEvent(AIUIEvent event) {
        //AIChatActivity 自己处理
        publishAIUIEventMessage(ACTION_AIUI_LISTENER_DATA, event);

        switch (event.eventType) {
            case AIUIConstant.EVENT_CONNECTED_TO_SERVER:
                String uid = event.data.getString("uid");
                LogUtil.d(TAG+ "已连接服务器,uid：" + uid);
                break;

            case AIUIConstant.EVENT_SERVER_DISCONNECTED:
                LogUtil.d(TAG+ "与服务器断开连接");
                break;

            case AIUIConstant.EVENT_WAKEUP:
                LogUtil.d(TAG+ "进入识别状态");
                break;
            case AIUIConstant.CMD_STOP_SAVE: //TTS 播放完毕
                if (event.arg1 == 5) { //语音合成完毕
                    //把消息推送出去
                    publishAIUIEventMessage(ACTION_AIUI_TTS_RESULT, event);
                }
                break;
            case AIUIConstant.EVENT_RESULT:

                //处理语音合成结果
                if (event.info.contains("\"sub\":\"tts")) {
                    dealWithTTS(event);
                    return;
                }
                //处理识别结果
                if (event.info.contains("\"sub\":\"iat")) {
                    dealWithIAT(event);
                }
                //处理语义结果
                else if (event.info.contains("\"sub\":\"nlp")) {
                    dealWithNLP(event);
                }
                break;

            case AIUIConstant.EVENT_ERROR:
                TTSIsStart = false;
                if (event.arg1 == 10120) {
//                    ToastUtils.showCustomLongToast(com.sanag.common.R.string.n_error_7);
                } else if (event.arg1 == 11200) {
                    LogUtil.e("发音人未授权");
//                    ToastUtils.show("发音人未授权");
                }
                LogUtil.d("test==>错误码: " + event.arg1);
                LogUtil.d("test==>错误信息:" + event.info);
                LogUtil.d("test==>解决方案:" + ErrorCode.getError(event.arg1) + "\n  错误解决详情参考：https://www.yuque.com/iflyaiui/zzoolv/igbuol");
                break;

            case AIUIConstant.EVENT_VAD:
                if (AIUIConstant.VAD_BOS == event.arg1) {
                    stringBuffer.append(asrResult);
                    LogUtil.d(TAG+"开始说话 vad_bos");

                    if (onAiUiRecognizeListener != null) {
                        onAiUiRecognizeListener.onStartSpeaking();
                    }
                } else if (AIUIConstant.VAD_BOS_TIMEOUT == event.arg1) {

                    LogUtil.d(TAG+"长时间不说话,前端点超时");
                    LogUtil.d(TAG+"asrResult = " + asrResult);
                } else if (AIUIConstant.VAD_EOS == event.arg1) {
                    LogUtil.d(TAG+ "结束说话 vad_eos");

                } else if (AIUIConstant.VAD_VOL == event.arg1) {
                    //回调太多，一般情况下可以注释掉
//                    KLog.d(TAG, "vad vol,说话音量:" + event.arg2);
                }
                break;
            case AIUIConstant.EVENT_SLEEP:
                LogUtil.d(TAG+ "设备休眠");
//                AIUIMessage wakeupMsg = new AIUIMessage(AIUIConstant.CMD_WAKEUP, 0, 0, "", null);
//                mAIUIAgent.sendMessage(wakeupMsg);
                break;

            case AIUIConstant.EVENT_START_RECORD:
              LogUtil.d(TAG+ "开始录音");
                break;

            case AIUIConstant.EVENT_STOP_RECORD:
              LogUtil.d(TAG+ "停止录音");
                stopRecord();
                break;

            case AIUIConstant.EVENT_STATE:    // 状态事件
                mAIUIState = event.arg1;
                if (AIUIConstant.STATE_IDLE == mAIUIState) {
                    // 闲置状态，AIUI未开启
                  LogUtil.d(TAG+ "aiui状态:STATE_IDLE");
                } else if (AIUIConstant.STATE_READY == mAIUIState) {
                    // AIUI已就绪，等待唤醒
                  LogUtil.d(TAG+ "aiui状态:STATE_READY");

                } else if (AIUIConstant.STATE_WORKING == mAIUIState) {
                    // AIUI工作中，可进行交互
                  LogUtil.d(TAG+ "aiui状态:STATE_WORKING");
                }
                break;

            default:
                break;
        }

    }

    private void dealWithTTS(AIUIEvent event) {
        //无意义词不处理
        if (event.data.getString("sid").equals(senselessWordUtil.nonsenseSid)) {
            AiuiEngine.TTS_stop();
            return;
        }
        //把消息推送出去
        publishAIUIEventMessage(ACTION_AIUI_TTS_RESULT, event);
    }

    private void dealWithIAT(AIUIEvent event) {
        if (Objects.equals(event.data.getString("tag"), "recognize_over")) {
            if (onMsgWriteAudioListener != null) {
                onMsgWriteAudioListener.onRecognizeOver();
            }
        }
        JSONObject cntJson = JSON.parseObject(new String(event.data.getByteArray("0"),
                StandardCharsets.UTF_8));
        if (cntJson == null) {
            return;
        }
        JSONObject text = cntJson.getJSONObject("text");

        //识别结果
        String asrResult = StreamingAsrUtil.processIATResult(text);

        if (text.getBoolean("ls")) {  //是否最后一句

            if (onAiUiRecognizeListener != null) {
                onAiUiRecognizeListener.onAsrNoSplicingResultEnd(true);
            }
        } else {
            if (onAiUiRecognizeListener != null) {
                onAiUiRecognizeListener.onAsrNoSplicingResultEnd(false);
            }
        }


//                    stringBuffer.append(asrResult);
        this.asrResult = asrResult;
        LogUtil.d("test==》asrResult = " + asrResult);

        String result = stringBuffer.toString() + asrResult;
        if (onAiUiRecognizeListener != null) {
            onAiUiRecognizeListener.onAsrResult(result);
            onAiUiRecognizeListener.onAsrNoSplicingResult(asrResult);
        } else {
            LogUtil.w("test==》onAiUiRecognizeListener 为空！！！");
        }

        if (onMsgWriteAudioListener != null) {
            onMsgWriteAudioListener.onRecognizeResult(result);
        }

    }

    public boolean onAiUiRecognizeListenerIsNull() {
        return onAiUiRecognizeListener == null;
    }

    private void dealWithNLP(AIUIEvent event) {
        //收到语义结果，说明还在交互，重置交互时间
//                    InteractUtil.resetTimer();
        if (Objects.equals(event.data.getString("tag"), "recognize_over")) {
            LogUtil.d("onMsgWriteAudioListener =" + onMsgWriteAudioListener);
            if (onMsgWriteAudioListener != null) {
                onMsgWriteAudioListener.onRecognizeOver();
            }
            LogUtil.d("onRecognizeOver222");
        }
        JSONObject cntJson = JSON.parseObject(new String(event.data.getByteArray("0"), StandardCharsets.UTF_8));
        JSONObject nlpResult = cntJson.getJSONObject("intent");
        //nlp无结果不处理
        if (nlpResult == null || nlpResult.isEmpty()) {
            return;
        }
        //如果只判断asr结果中的无意义词，若nlp先返回就可能被错误判断为无意义词
        String asrResult = nlpResult.getString("text");
        meaningful = senselessWordUtil.isMeaningful_filter1word(asrResult);
        //无意义词不处理
        if (!meaningful) {
            senselessWordUtil.nonsenseSid = event.data.getString("sid");
            LogUtil.d(TAG+"无意义请求的sid=" + senselessWordUtil.nonsenseSid);
            return;
        }
        LogUtil.d(TAG+ "nlp result :" + nlpResult);
        //在线语义结果,rc=0语义理解成功，rc≠0语义理解失败
//                    KLog.d(nlpResult.toString());
    }

    private boolean isFirstFrame = true; //判断是不是wav的第一帧，如果是要去掉前面44字节

    /**
     * 读取外部音频写入 CAE SDK
     */

    private static final int SAMPLE_RATE = 16000; // 采样率
    private static final int CHANNEL_COUNT = 1; // 声道数
    private static final int AUDIO_FORMAT = AudioFormat.ENCODING_PCM_16BIT; // 16位PCM

    private static final int READ_SIZE = 1280; // 读取大小，即每次读取的字节数

    /**
     * 读取外部音频写入 CAE SDK
     */
//    public void writeAudioTest(String filePath) {
//        clearRecognitionText();
//        if (isRecording || EngineConstants.isWriting) {
//            return;
//        }
//        EngineConstants.isWriting = true;
//
//        Disposable subscribe =
//                Observable.create((ObservableOnSubscribe<Boolean>) emitter -> {
//                            InputStream in;
//                            try {
//                                byte[] audio = new byte[READ_SIZE];//1声道1ms有32bytes数据。一次只送部分数据去识别
//                                in = new FileInputStream(filePath);
//
//                                AiuiEngine.MSG_wakeup(EngineConstants.WAKEUPTYPE_VOICE);
//                                isFirstFrame = true;
//                                // 流式读取文件写入aiui
//                                while (in.read(audio) != -1) {
//                                    if (!EngineConstants.isWriting) {
//                                        KLog.d("dieOff");
//                                        break;
//                                    }
//
//                                    if (filePath.endsWith("wav") && isFirstFrame) {
//                                        isFirstFrame = false;
//                                        //去掉wav的44字节文件头
//                                        byte[] filterWavHeaderData = new byte[audio.length - 44];
//                                        System.arraycopy(audio, 44, filterWavHeaderData, 0, filterWavHeaderData.length);
//                                        //写入音频给aiui去识别
//                                        AiuiEngine.MSG_writeAudio(filterWavHeaderData);
//                                    } else {
//                                        AiuiEngine.MSG_writeAudio(audio);
//                                    }
//                                    Thread.sleep(25);
//                                }
//                                KLog.i(TAG, "音频读取完成");
//                                in.close();
//                                //发送文本请求-后台
//                                AiuiEngine.MSG_writeOverAudio();
//
//                                EngineConstants.isWriting = false;
//                                emitter.onNext(true);
//
//                            } catch (Exception e) {
//                                e.printStackTrace();
//                                KLog.i(TAG, "音频读取失败");
//                                EngineConstants.isWriting = false;
//                                emitter.onNext(false);
//                            }
//
//                        })
//                        .subscribeOn(Schedulers.io())
//                        .observeOn(AndroidSchedulers.mainThread())
//                        .subscribe(result -> {
//                            if (onMsgWriteAudioListener != null) {
//                                if (result) {
//                                    onMsgWriteAudioListener.onWriteAudioOver(true);
//                                } else {
//                                    onMsgWriteAudioListener.onWriteAudioOver(false);
//                                }
//                            }
//                        }, throwable -> {
//                            if (onMsgWriteAudioListener != null) {
//                                onMsgWriteAudioListener.onWriteAudioOver(false);
//                            }
//                        });
//        register(subscribe);
//    }


    public interface OnMsgWriteAudioListener {
        void onWriteAudioOver(boolean readSuccess);


        void onRecognizeResult(String result);

        void onRecognizeOver();
    }

    private OnAiUiRecognizeListener onAiUiRecognizeListener;

    public void setOnAiUiRecognizeListener(OnAiUiRecognizeListener onAiUiRecognizeListener) {
        this.onAiUiRecognizeListener = onAiUiRecognizeListener;
    }

    public void setOnAiUiRecognizeListenerAndClear(OnAiUiRecognizeListener onAiUiRecognizeListener) {
        clearRecognitionText();
        this.onAiUiRecognizeListener = onAiUiRecognizeListener;
    }

    public interface OnAiUiRecognizeListener {
        default void onStartSpeaking() {
        }

        ;

        void onAsrResult(String result);

        default void onAsrNoSplicingResult(String result) {
        }  //不拼接数据的识别结果回调

        default void onAsrNoSplicingResultEnd(boolean isResultEnd) {
        }  //识别结束监听

        void onRecordStatus(boolean recording);
    }

    private OnMsgWriteAudioListener onMsgWriteAudioListener;

    public void setOnMsgWriteAudioListener(OnMsgWriteAudioListener onMsgWriteAudioListener) {
        this.onMsgWriteAudioListener = onMsgWriteAudioListener;
    }



    // 停止文件写入识别
    public void onDieOff() {
        EngineConstants.isWriting = false;
    }

    // 动态设置speech_timeout时间
    private void setSpeechTimeout(float thold, long eos, long millSecond) {
        if (!checkAIUIEngine()) return;
        String setParams =
                "{\"vad\":{\"threshold\":\"" + thold + "\"," +
                        "\"speech_timeout\":\"" + millSecond + "\"}}";
//        String setParams =
//                "{\"vad\":{\"vad_eos\":\"" + eos + "\",\"speech_timeout\":\"" + millSecond +
//                "\"}}";
//        String setParams =
//                "{\"vad\":{\"vad_eos\":\"" + eos + "\",\"threshold\":\"" + thold + "\"," +
//                        "\"speech_timeout\":\"" + millSecond + "\"}}";
        AIUIMessage setMsg = new AIUIMessage(CMD_SET_PARAMS, 0, 0, setParams, null);
        mAIUIAgent.sendMessage(setMsg);
    }
}
